package com.yzg.lock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.StampedLock;

/**
 * @author misterWei
 * @create 2020年06月26号:18点22分
 * @mailbox forcontinue@163.com
 * 读写锁示范,无锁,时间戳方式
 */
@Slf4j(topic = "c.StampedLockTest")
public class StampedLockTest {
  static   StampedLock lock = new StampedLock();
   static int tempRead = 0;

    public static void main(String[] args) {
        DataSource dataSource = new DataSource();
        for (int i = 0; i < 5; i++) {
            int j = i;
            new Thread(()->{
                if (j == 3)
                    dataSource.write(j);
                try {
                    dataSource.read();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    @Slf4j(topic = "c.DataSource")
   static class DataSource{
        public int read() throws InterruptedException {
           // 乐观读锁
            long optimisticRead = lock.tryOptimisticRead();
            Thread.sleep(2000);
            if (lock.validate(optimisticRead)) {
                log.info("乐观锁读取--无锁方式{}",optimisticRead);
                return  tempRead;
            }
            //乐观锁失败,就需要锁升级为读锁
            log.info("读锁读取--并发读锁方式");
            optimisticRead = lock.readLock();
            try {
                return tempRead;
            }finally {
                log.info("读锁释放{}",optimisticRead);
                lock.unlockRead(optimisticRead);
            }
        }
        public void write(int temp){
            log.info("写锁方式");
            long optimisticRead = lock.writeLock();
            try {
                tempRead = temp;
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                log.info("释放写锁{}",optimisticRead);
                lock.unlockWrite(optimisticRead);
            }
        }
   }
}
